package com.base.components.common.doc.swagger2;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * SwaggerGatewayController 用于拓展 swagger-bootstrap-ui v1.8.7
 * https://gitee.com/xiaoym/swagger-bootstrap-ui
 *
 * @author <a href="drakelee1221@gmail.com">LiGeng</a>
 * @version v1.0.0
 * @date 2018-12-17 14:08
 */
@Controller
@ConditionalOnProperty(name = "api-doc.swagger.gateway.enabled", havingValue = "true")
public class SwaggerGatewayController {
  private static final String DOC_RESOURCE_PATH = "classpath:/META-INF/resources/doc.html";
  private static final String BASE_JS_SRC = "webjars/bycdao-ui/cdao/swaggerbootstrapui.js";
  private static final String BASE_JS_EXTEND_SRC = "webjars/swagger-ui-extend/swaggerbootstrapui-extend.js";
  private static final String EXTEND_JS_PATH = "webjars/swagger-ui-extend/extend.js";
  private static volatile String docHtml;

  @GetMapping(value = "/doc.html", produces = MediaType.TEXT_HTML_VALUE)
  public void apiDoc(HttpServletResponse response){
        response.setContentType(MediaType.TEXT_HTML_VALUE);
        response.setCharacterEncoding("UTF-8");
    try (PrintWriter writer = response.getWriter()){
      writer.write(getDocHtml());
    } catch (IOException e) {
      throw new RuntimeException("fail to open api doc.html", e);
    }
  }

  private String getDocHtml() throws IOException {
    if (docHtml == null) {
      synchronized(SwaggerGatewayController.class) {
        if (docHtml == null) {
          ResourceLoader resourceLoader = new DefaultResourceLoader();
          Resource resource = resourceLoader.getResource(DOC_RESOURCE_PATH);
          if(resource.exists()){
            Document document = Jsoup.parse(resource.getInputStream(), "UTF-8", "/");
            Elements scripts = document.getElementsByTag("script");
            for (Element script : scripts) {
              String src = script.attr("src");
              if(src != null && src.contains(BASE_JS_SRC)){
                int i = src.indexOf("?");
                script.attr("src", BASE_JS_EXTEND_SRC + (i>=0?src.substring(i):""));
                break;
              }
            }
            document.head().append("<script src='" + EXTEND_JS_PATH + "'></script>");
            docHtml = document.toString();
          }
        }
      }
    }
    return docHtml;
  }
}
